/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.ykdl.member.views;

import java.util.Calendar;
import java.util.Date;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.ykdl.member.kid.R;

public class DatePickerWheel extends FrameLayout {
	private Context mContext;

	private static final int DEFAULT_START_YEAR = 1900;
	private static final int DEFAULT_END_YEAR = 2014;
	private WheelView mYearWheel, mMonthWheel, mDayWheel;
	private OnDateChangedListener mOnDateChangedListener;
	private Calendar mMinDate, mMaxDate, mCurrentDate, mTempDate;
	private LinearLayout mLayoutDayWheel,mLayoutMonthWheel;

	public interface OnDateChangedListener {

		void onDateChanged(DatePickerWheel view, int year, int monthOfYear,
				int dayOfMonth);
	}

	public DatePickerWheel(Context context) {
		this(context, null);
	}

	public DatePickerWheel(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public DatePickerWheel(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		mContext = context;

		mCurrentDate = Calendar.getInstance();
		mCurrentDate.setTimeInMillis(System.currentTimeMillis());
		mTempDate = Calendar.getInstance();
		mMinDate = Calendar.getInstance();
		setMinDate(new Date(DEFAULT_START_YEAR, 0, 1).getTime());
		mMaxDate = Calendar.getInstance();
		setMaxDate(new Date(DEFAULT_END_YEAR, 11, 31).getTime());

		// 找到dialog的布局文件
		LayoutInflater inflater = LayoutInflater.from(mContext);
		inflater.inflate(R.layout.date_picker_wheel, this, true);

		// 年
		mYearWheel = (WheelView) findViewById(R.id.year);
		mYearWheel.setCyclic(false);// 可循环滚动
		mYearWheel.setLabel("年");// 添加文字

		// 月
		mMonthWheel = (WheelView) findViewById(R.id.month);
		mMonthWheel.setAdapter(new NumericWheelAdapter(1, 12));
		mMonthWheel.setCyclic(false);
		mMonthWheel.setLabel("月");

		// 日
		mDayWheel = (WheelView) findViewById(R.id.day);
		mDayWheel.setCyclic(false);
		mDayWheel.setLabel("日");
		
		mLayoutDayWheel = (LinearLayout) findViewById(R.id.layoutDayWheel);
		mLayoutMonthWheel = (LinearLayout) findViewById(R.id.layoutMonthWheel);

		OnWheelChangedListener listener = new OnWheelChangedListener() {

			@Override
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				long time = mCurrentDate.getTimeInMillis();
				mTempDate.setTimeInMillis(time);

				if (wheel == mDayWheel) {
					int maxDayOfMonth = mTempDate
							.getActualMaximum(Calendar.DAY_OF_MONTH);
					if (oldValue == maxDayOfMonth - 1 && newValue == 0) {
						mTempDate.add(Calendar.DAY_OF_MONTH, 1);
					} else if (oldValue == 0 && newValue == maxDayOfMonth - 1) {
						mTempDate.add(Calendar.DAY_OF_MONTH, -1);
					} else {
						mTempDate.add(Calendar.DAY_OF_MONTH, newValue
								- oldValue);
					}

				} else if (wheel == mMonthWheel) {
					if (oldValue == 11 && newValue == 0) {
						mTempDate.add(Calendar.MONTH, 1);
					} else if (oldValue == 0 && newValue == 11) {
						mTempDate.add(Calendar.MONTH, -1);
					} else {
						mTempDate.add(Calendar.MONTH, newValue - oldValue);
					}
				} else if (wheel == mYearWheel) {
					mTempDate.set(Calendar.YEAR,
							newValue + mMinDate.get(Calendar.YEAR));
				} else {
					throw new IllegalArgumentException();
				}
				// now set the date to the adjusted one
				setDate(mTempDate.get(Calendar.YEAR),
						mTempDate.get(Calendar.MONTH),
						mTempDate.get(Calendar.DAY_OF_MONTH));
				setRange();
				notifyDateChanged();

			}

		};

		mTempDate.clear();
		mYearWheel.addChangingListener(listener);
		mMonthWheel.addChangingListener(listener);
		mDayWheel.addChangingListener(listener);
	}

	public int getYear() {
		return mYearWheel.getCurrentItem() + mMinDate.get(Calendar.YEAR);
	}

	public int getMonth() {
		return mCurrentDate.get(Calendar.MONTH);
	}

	public int getDay() {
		return mCurrentDate.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * Notifies the listener, if such, for a change in the selected date.
	 */
	private void notifyDateChanged() {
		if (mOnDateChangedListener != null) {
			mOnDateChangedListener.onDateChanged(this, getYear(), getMonth(),
					getDay());
		}
	}

	public void init(int year, int monthOfYear, int dayOfMonth,
			OnDateChangedListener onDateChangedListener) {
		setDate(year, monthOfYear, dayOfMonth);
		setRange();
		mOnDateChangedListener = onDateChangedListener;
	}

	private void setRange() {
		if (mCurrentDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)) {
			if (mCurrentDate.get(Calendar.MONTH) == mMinDate
					.get(Calendar.MONTH)) {
				mDayWheel.setAdapter(new NumericWheelAdapter(mMinDate
						.get(Calendar.DAY_OF_MONTH), mCurrentDate
						.getActualMaximum(Calendar.DAY_OF_MONTH)));
			} else {
				mDayWheel.setAdapter(new NumericWheelAdapter(1, mCurrentDate
						.getActualMaximum(Calendar.DAY_OF_MONTH)));
			}

			mMonthWheel.setAdapter(new NumericWheelAdapter(mMinDate
					.get(Calendar.MONTH) + 1, 12));
		} else if (mCurrentDate.get(Calendar.YEAR) == mMaxDate
				.get(Calendar.YEAR)) {
			if (mCurrentDate.get(Calendar.MONTH) == mMaxDate
					.get(Calendar.MONTH)) {
				mDayWheel.setAdapter(new NumericWheelAdapter(1, mMaxDate
						.get(Calendar.DAY_OF_MONTH)));
			} else {
				mDayWheel.setAdapter(new NumericWheelAdapter(1, mCurrentDate
						.getActualMaximum(Calendar.DAY_OF_MONTH)));
			}

			mMonthWheel.setAdapter(new NumericWheelAdapter(1, mMaxDate
					.get(Calendar.MONTH) + 1));
		} else {
			mDayWheel.setAdapter(new NumericWheelAdapter(1, mCurrentDate
					.getActualMaximum(Calendar.DAY_OF_MONTH)));

			mMonthWheel.setAdapter(new NumericWheelAdapter(1, 12));

		}

		mYearWheel.setAdapter(new NumericWheelAdapter(mMinDate
				.get(Calendar.YEAR), mMaxDate.get(Calendar.YEAR)));

		mYearWheel.setCurrentItem(
				mCurrentDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR),
				false);
		if (mCurrentDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)) {
			mMonthWheel.setCurrentItem(mCurrentDate.get(Calendar.MONTH)
					- mMinDate.get(Calendar.MONTH), false);
			if (mCurrentDate.get(Calendar.MONTH) == mMinDate
					.get(Calendar.MONTH)) {
				mDayWheel.setCurrentItem(
						mCurrentDate.get(Calendar.DAY_OF_MONTH)
								- mMinDate.get(Calendar.DAY_OF_MONTH), false);
			} else {
				mDayWheel.setCurrentItem(
						mCurrentDate.get(Calendar.DAY_OF_MONTH) - 1, false);
			}

		} else {
			mMonthWheel.setCurrentItem(mCurrentDate.get(Calendar.MONTH), false);
			mDayWheel.setCurrentItem(
					mCurrentDate.get(Calendar.DAY_OF_MONTH) - 1, false);
		}

	}

	private void setDate(int year, int month, int dayOfMonth) {
		mCurrentDate.set(year, month, dayOfMonth);
		if (mCurrentDate.before(mMinDate)) {
			mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
		} else if (mCurrentDate.after(mMaxDate)) {
			mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
		}
	}

	public long getMinDate() {
		return mMinDate.getTimeInMillis();
	}

	public void setMinDate(long minDate) {
		mMinDate.setTimeInMillis(minDate);
		if (mCurrentDate.before(mMinDate)) {
			mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
		}
	}

	public long getMaxDate() {
		return mMaxDate.getTimeInMillis();// mCalendarView.getMaxDate();
	}

	public void setMaxDate(long maxDate) {
		mMaxDate.setTimeInMillis(maxDate);
		if (mCurrentDate.after(mMaxDate)) {
			mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
		}
	}

	public void hideDayPicker() {
		mDayWheel.setVisibility(View.GONE);
		//mLayoutMonthWheel.setBackgroundResource(R.drawable.bg_wheel3);
		mLayoutDayWheel.setVisibility(View.GONE);
	}

}
